<?php
class FluxoContrato implements InterfaceFluxo
{
    public static function getAlertsStatus($pfcid)
    {
        global $usuario;
        
        $array = array();
        
        switch ($pfcid) {
            case PerfilComportamental::Gabinete:
                $array = array(Status::Contrato_EncaminhadoGabinete);
                break;
                
            case PerfilComportamental::Orgao:
                $array = array(
                        Status::Contrato_CadastroFinalizado,
                        Status::Contrato_CadastroRecusado);
                break;
        }
        
        if ($usuario->isSam()) {
            $array[] = Status::Contrato_Cadastrado;
        }
            
        return $array;
    }
    
    public static function loadAlertsData($pfcid) 
    {
        $status = self::getAlertsStatus($pfcid);
        if ($status) {
            global $usuario;
            
            $status = TUtils::ArrayToSql($status);
            
            $view = new ViewContratos();
            $where = 'statusid IN (' . $status . ')';
            
            $contratoids = $usuario->listarContratosSQL();
            if ($contratoids) {
                $where .= ' AND contratoid in (' . $contratoids . ')';
            }
            
            $result = $view->listar(array('precondicao'=>$where));
            if (pg_num_rows($result)>0) {
                return pg_fetch_all($result);
            }
        }
    }
    
    // ----
    
    protected static function verificarPrecondicoesGlobais($contrato, $throwsException = FALSE)
    {
    	//TODO: fazer. cuidado com o cadastro de contrato, onde o $contrato->ativo será NULL ou FALSE
    	if ($contrato->statusid == NULL) {
    		return TRUE;
    	}
    	
    	if ($contrato->ativo == FALSE) {
    		if ($throwsException) {
    			throw new Exception('Precondição não atendida.');
    		}
    		else {
    			return FALSE;
    		}
    	}
    	else {
    		return TRUE;
    	}
    	
		return TRUE;
    }
    
    public static function inserir(Contrato $contrato)
    {
    	self::isAuthorized('cadastrar', $contrato, $throwsException = TRUE);
    	
    	try {
        	pg_query(conexao::Conectar(), "begin");
        	
    		$contrato->statusid = Status::Contrato_Cadastrado;
    		$contrato->ativo = TRUE;
    		$contrato->salvar();
    		$contrato->criarLotacoesContrato();
    		
    		pg_query(conexao::Conectar(), "commit");
    	}
    	catch (Exception $e) {
    	    pg_query(conexao::Conectar(), "rollback");
    	    throw new Exception($e->getMessage());
    	}
    }
    
    public static function alterar(Contrato $contrato, $justificativasAditivo)
    {
        self::isAuthorized('alterar', $contrato, $throwsException = TRUE);
        
        try {
            pg_query(conexao::Conectar(), "begin");
            
        	if ($contrato->isAditivo() AND $justificativasAditivo !== NULL) {
                $contrato->alterarJustificativasAditivo($justificativasAditivo, FALSE);
            }
    
            $bdContrato = new Contrato($contrato->contratoid);
            $bdOrgao = $bdContrato->getOrgao();
            
            if ($bdOrgao->orgaoid == $contrato->orgaoid) {
            	$contrato->salvar();
            }
            else {
            	$contrato->salvar();
            	$contrato->excluirLotacoesContrato($bdOrgao->orgaoid);  
            	$contrato->criarLotacoesContrato();		
            }
            
            pg_query(conexao::Conectar(), "commit");
        }
        catch (Exception $e) {
            pg_query(conexao::Conectar(), "rollback");
            throw new Exception($e->getMessage());
        }
    }
    
    public static function inserirAditivo(Contrato $contrato, Contrato $aditivo, $justificativas)
    {
        self::isAuthorized('aditivoscontrato', $contrato, $throwsException = TRUE);
        
        try {
			pg_query(conexao::Conectar(), "begin");
			
			if ($contrato->ativo != TRUE
			    OR $contrato->statusid != Status::Contrato_CadastroConfirmado) {
			    throw new Exception('Criação de Aditivo não permitida,
			    pois este contrato está inativo ou em fase de cadastramento.');
			}
			
			//Salvando o aditivo
			$aditivo->contratooriginalid = $contrato->contratoid;
			//TODO: estava = FALSE na linha abaixo. Por que?
			$aditivo->ativo = TRUE;
			$aditivo->statusid = Status::Contrato_Cadastrado;
			
			$aditivo->salvar();		    
			
			$aditivo->criarLotacoesAditivo();
			
		    //Copiando Salarios
		    $salario = new Salario();
		    $criterio = array('campo'    => 'contratoid',
		                      'operador' => '=',
		                      'valor'    => $contrato->contratoid);
		    $resultado = $salario->listar($criterio);
			$data = pg_fetch_all($resultado);
			if ($data) {
            	foreach ($data as $d) {
					$sal = new Salario($d['salarioid']);
					$sal->salarioid = NULL;
					$sal->contratoid = $aditivo->contratoid;
					$sal->salvar();
				}
			}
			
			// Justificativas
			if ($justificativas) {
			    foreach ($justificativas as $j) {
			        $justificativaAditivo = new JustificativaAditivo();
			        $justificativaAditivo->contratoid = $aditivo->contratoid;
			        $justificativaAditivo->motivoaditivoid = $j;
			        $justificativaAditivo->salvar();
			    }
			}
			
	        // UPDATE vagas
			$sql = 'UPDATE vaga SET contratoid = '. $aditivo->contratoid .
			       'WHERE contratoid = ' . $aditivo->contratooriginalid;   	        
	        $resultado = TSqlSelect::customSelect($sql);
	        
	        // Desativando contratos e aditivos anteriores
			$sql = "UPDATE " . $contrato->getTableName() . " 
					SET ativo = FALSE 
					WHERE 
						( 
							contratoid = " . $aditivo->contratooriginalid . " OR 
							contratooriginalid = " . $aditivo->contratooriginalid . "
						) AND 
						contratoid <> " . $aditivo->contratoid;
			
			$resultado = TSqlSelect::customSelect($sql);
			
			pg_query(conexao::Conectar(), "commit");
    	          
		}
		catch (Exception $e) {
                pg_query(conexao::Conectar(), "rollback");
                throw new Exception($e->getMessage());
		}
		
		return $aditivo->contratoid;
    }
    
    public static function finalizar(Contrato $contrato, $parecer)
    {
    	if ($contrato->hasSalarios() == FALSE) {
	    	throw new Exception('O cadastro deste contrato não pode ser finalizado, pois existem cargos sem salários.');
    	}
	    $contrato->statusid = Status::Contrato_CadastroFinalizado;
	    $contrato->setParecer($parecer);
	    $contrato->salvar();
    }
    
    public static function encaminhar(Contrato $contrato, $parecer)
    {
        self::isAuthorized('encaminhar', $contrato, $throwsException = TRUE);
        
    	if ($contrato->hasSalarios() === FALSE){
	        throw new Exception('Este contrato não pode ser encaminhado para o núcleo central, pois existem cargos que não possui nenhum salário cadastrado.');
	    }
	    
	    if ($contrato->hasVagasLotadas() === FALSE){
	        throw new Exception('Este contrato não pode ser encaminhado para o núcleo central, pois não possui nenhuma vaga lotada.');
	    }
	    
	    $contrato->statusid = Status::Contrato_EncaminhadoGabinete;
	    $contrato->setParecer($parecer);
	    $contrato->salvar();
    }
    
    public static function confirmar(Contrato $contrato, $parecer)
    {
        self::isAuthorized('aprovar', $contrato, $throwsException = TRUE);
        
    	$contrato->statusid = Status::Contrato_CadastroConfirmado;
	    $contrato->ativo = TRUE;
	    $contrato->setParecer($parecer);
	    $contrato->salvar();
    }
    
    public static function recusar(Contrato $contrato, $parecer)
    {
        self::isAuthorized('reprovar', $contrato, $throwsException = TRUE);
        
    	$contrato->statusid = Status::Contrato_CadastroRecusado;
	    $contrato->setParecer($parecer);
	    $contrato->salvar();
    }
    
    /*
     * Autoriza a exibição de botões de fluxo
     */
    public static function isAuthorized($operacao, Contrato $contrato, $throwsException = FALSE)
    {
    	global $usuario;
    	global $pfcid;
    	
    	if (!self::verificarPrecondicoesGlobais($contrato)) {
    		return FALSE;
    	}
    	
    	switch ($operacao) {
    		
	    	case 'cadastrar':
	    		if ($usuario->isSam() AND
	    			$contrato->statusid == NULL) {
	    			return TRUE;
	    		}
	    		break;
	    	
	    	case 'alterar':
	    	    if ($usuario->isSam() AND
	    		($contrato->statusid == Status::Contrato_Cadastrado OR
	    		$contrato->statusid == Status::Contrato_CadastroFinalizado OR
	    		$contrato->statusid == Status::Contrato_CadastroRecusado))
	    			return TRUE;
	    		break;
	    		
	    	case 'finalizar':
	    		if ($usuario->isAuthorized(Operacao::CONTRATO_FINALIZARCADASTRO) AND
					$contrato->statusid == Status::Contrato_Cadastrado) {
					return TRUE;
				}
	    		break;
	    		
	    	case 'encaminhar':
	    		if ($pfcid == PerfilComportamental::Orgao AND
	    			$usuario->orgaoid == $contrato->orgaoid AND
	    			($contrato->statusid == Status::Contrato_CadastroFinalizado OR
	    			$contrato->statusid == Status::Contrato_CadastroRecusado))
	    			return TRUE;
	    		break; 
	    	case 'aprovar':
	    	case 'reprovar':
	    		if ($pfcid == PerfilComportamental::Gabinete AND
	    			$usuario->isAuthorized(Operacao::CONTRATO_APROVARREPROVAR) AND
	    			$contrato->statusid == Status::Contrato_EncaminhadoGabinete) {
	    			return TRUE;
	    		}
	    		break;
	    	case 'aditivoscontrato':
	    		if ($contrato->statusid == Status::Contrato_CadastroConfirmado AND
	    			$usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_ADITIVOS)) {
	    			return TRUE;
	    		}
	    		break;
    	}
    	
    	if ($throwsException) {
    	    throw new Exception('Você não tem autorização para essa operação.');
    	}
    }
    
    /*
     * Gerencia a exibição das abas
     */
    public static function isVisible($operacoes, $redirect = TRUE)
    {
    	global $usuario;
    	
    	foreach ($operacoes as $operacao) {
    		if ($usuario->isAuthorized($operacao)) {
    			return TRUE;
    		}
    	}
    	
    	if ($redirect) {
    		$usuario->redirectUnauthorized();
    	}
    }
    
    /*
     * Gerencia se o usuário poderá editar ou apenas visualizar
     * determinadas telas
     */
    public static function isEditable($controller, Contrato $contrato = NULL)
    {
    	global $usuario;
    	
    	if (!self::verificarPrecondicoesGlobais($contrato)) {
    		return FALSE;
    	}
    	
    	switch ($controller) {
    		
    		case 'contratos':
    			if ($usuario->isSam() AND
    				$contrato->statusid == NULL) {
    				return TRUE;
    			}
    			if ($usuario->isSam() AND
    				($contrato->statusid == Status::Contrato_Cadastrado OR
	    		    $contrato->statusid == Status::Contrato_CadastroFinalizado OR
	    		    $contrato->statusid == Status::Contrato_CadastroRecusado)) {
    				return TRUE;
    			}
    			break;
    		
    		case 'aditivoscontrato':
		    	if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_ADITIVOS) AND
		    		$contrato->statusid == Status::Contrato_CadastroConfirmado) {
		    			return TRUE;
		    		}
		    	break;
		    	
    		case 'lotacoescontrato':
    			if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_LOTACOES)) {
    			    if ($contrato->numeroaditivo == NULL) {
        				if ($contrato->statusid == Status::Contrato_CadastroFinalizado OR
        					$contrato->statusid == Status::Contrato_CadastroRecusado) {
        					return TRUE;
        				}
    			    }
    			    else {
    			        $motivos = array(MotivoAditivo::MOTIVO_QUANTIDADE);
    			        if ($contrato->hasMotivosAditivo($motivos)) {
    			            return TRUE;
    			        }
    			    }
    			}
    			break;
    			
    		case 'vagas':
    			if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_VAGAS)) {
    				if ($contrato->numeroaditivo == NULL) {
    					if ($contrato->statusid == Status::Contrato_Cadastrado OR
    						$contrato->statusid == Status::Contrato_CadastroFinalizado OR
    						$contrato->statusid == Status::Contrato_CadastroRecusado) {
    						return TRUE;
    					}
    				}
    				else {
    					$motivos = array(MotivoAditivo::MOTIVO_QUANTIDADE);
    					if ($contrato->hasMotivosAditivo($motivos)) {
    						return TRUE;
    					}
    				}
    			}
    			break;
    			
    		case 'vagaslotacoes':
    			if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_VAGASLOTACOES)) {
    				if ($contrato->numeroaditivo == NULL) {
                        if ($contrato->statusid == Status::Contrato_CadastroFinalizado OR
                        	$contrato->statusid == Status::Contrato_CadastroRecusado) {
                        	return TRUE;
                        }
    				}
                    else {
                        $motivos = array(MotivoAditivo::MOTIVO_QUANTIDADE);
                        if ($contrato->hasMotivosAditivo($motivos)) {
                            return TRUE;
                        }
                    }
    			}
    			break;
    			
    		case 'salarios':
    			if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_SALARIOS)) {
    				if ($contrato->numeroaditivo == NULL) {
    					if ($contrato->statusid == Status::Contrato_Cadastrado OR
    						$contrato->statusid == Status::Contrato_CadastroFinalizado OR
    						$contrato->statusid == Status::Contrato_CadastroRecusado
    						) {
    						return TRUE;
    					}
    				}
    				else {
    					$motivos = array(
    						MotivoAditivo::MOTIVO_QUANTIDADE,
    					    MotivoAditivo::MOTIVO_DISSIDIO_COLETIVO,
    						MotivoAditivo::MOTIVO_ALTERACAO_ENCARGOS_SOCIAIS,
    						MotivoAditivo::MOTIVO_ALTERACAO_TRIBUTOS,
    						MotivoAditivo::MOTIVO_ALTERACAO_BENEFICIOS);
    					if ($contrato->hasMotivosAditivo($motivos)) {
    						return TRUE;
    					}
    				}
    			}
    			break;
    			
    		case 'arquivoscontrato':
    			if ($usuario->isAuthorized(Operacao::CONTRATO_CADASTRAR_ARQUIVOS)) {
    				return TRUE;
    			}
    			break;
    	}
    }
    
    public static function isMensagemBrevidade($contrato)
    {
        global $pfcid;
        global $usuario;
        
        if ($contrato->isAditivo()) {
            
            $msg = NULL;
            
            // SAM
            if ($contrato->statusid == Status::Contrato_Cadastrado AND
                $usuario->isSam()) {
                $msg = 'O processo de cadastramento do aditivo deverá ser finalizado
                com brevidade, pois todas as vagas a partir desse momento estão bloqueadas
                para qualquer tipo de movimentação até que o mesmo seja aprovado pelo
                Núcleo Central';
            }
            
            // ORG
            if ($contrato->statusid == Status::Contrato_CadastroFinalizado AND
                $pfcid == PerfilComportamental::Orgao) {
                $msg = 'O processo de inclusão de dados complementares do aditivo
                    deverá ser finalizado com brevidade, pois todas as vagas estão
                    bloqueadas para qualquer tipo de movimentação até que o mesmo seja
                    aprovado pelo Núcleo Central.';
            }
            
            // NC
            if ($contrato->statusid == Status::Contrato_EncaminhadoGabinete AND
                $pfcid == PerfilComportamental::Gabinete) {
                $msg = 'O processo de aprovação do aditivo deverá ser finalizado com brevidade, pois todas as vagas estão bloqueadas para qualquer tipo de movimentação até que o mesmo seja aprovado.';
            }
            
            return $msg;
        }
        else {
            return FALSE;
        }        
        
    }
}